#include "schema.h"
//necessary
#include "memory-tools.h"
#include <string.h>

//TODO testing
static Pschema initSchema(SchemaClassType _class, char* _cid, int _arrayLength,Pschema _arrayType){
	Pschema result=(Pschema) mallocMemory(sizeof(Schema),"schema.c:initSchema:1");
	result->class=_class;
	result->className=_cid;
	result->arraylength=_arrayLength;
	result->arrayType=_arrayType;
	return result;
}

//TODO testing
Pschema initSchemaSimple(SchemaClassType _class){
	return initSchema(_class,SCHEMA_NOCLASS,SCHEMA_NOARRAY,NULL);
}

//TODO testing
Pschema initSchemaClass(char* _className){
	return initSchema(SCHEMA_CLASS,_className,SCHEMA_NOARRAY,NULL);
}

//TODO testing
Pschema initSchemaArray(int _arraylength, Pschema _arrayType){
	return initSchema(SCHEMA_ARRAY,SCHEMA_NOCLASS,_arraylength,_arrayType);
}

//TODO testing
void freeSchema(Pschema pobj){
	//className must not be freed here because it is contained in the syntax tree
	freeMemory(sizeof(Schema),pobj);
}

//TODO testing
void freeSchemaFull(Pschema pobj){
	if (pobj->arrayType!=NULL){
		freeSchemaFull(pobj->arrayType);
	}
	freeSchema(pobj);
}

//TODO testing
void printSchema(FILE* f,Pschema pobj){
	if (pobj==NULL){
		fprintf(f,"VOID");
	}
	if (pobj->class==SCHEMA_ARRAY){
		fprintf(f,"array[0..%03d]of ",pobj->arraylength);
		printSchema(f,pobj->arrayType);
	}
	if (pobj->class==SCHEMA_CLASS){
		fprintf(f,"class %s",pobj->className);
		return;
	}
	printSchemaClassType(f,pobj->class);
}

//TODO testing
static void dotSchemaRecursive(FILE* f,Pschema pobj,int idnode){
	fprintf(f,"n%03d [shape=record,label=\"",idnode);
	printSchemaClassType(f,pobj->class);
	fprintf(f,"|");

	if (strcmp(pobj->className,SCHEMA_NOCLASS)==0){
		fprintf(f,"-");
	}else{
		fprintf(f,"%s",pobj->className);
	}
	fprintf(f,"|");

	if (pobj->arraylength== SCHEMA_NOARRAY){
		fprintf(f,"-|-");
	}else{
		fprintf(f,"%d|goto",pobj->arraylength);
	}
	fprintf(f,"\"];\n");
	if (pobj->arrayType==NULL){
		fprintf(f,"n%03d -> n%03d;\n",idnode,idnode+1);
		dotSchemaRecursive(f,pobj->arrayType,idnode+1);
	}
}

//TODO testing
void dotSchemaFull(const char* filename,Pschema pobj){
	char dotname[strlen(filename)+10];
	char command[strlen(filename)*2+30];
	int result;

	sprintf(dotname,"grp/%s.dot",filename);
	FILE* dotfile=fopen(dotname,"w");
	if (dotfile == NULL){
		fprintf(stderr,"can't create \"%s\" file",dotname);
		return;
	}
	fprintf(dotfile,"digraph %s {\n",filename);
	dotSchemaRecursive(dotfile,pobj,1);
	fprintf(dotfile,"}\n");
	fflush(dotfile);
	fclose(dotfile);
	sprintf(command,"dot -Tjpg %s -o grp/%s.jpg",dotname,filename);
	result=system(command);
	if (!result){
		fprintf(stderr,"can't compile %s!\n",dotname);
		return;
	}
}

